<?php
namespace App\Models;

use App\Enums\GoodsBusinessEnum;
use App\Exceptions\ApiErrorException;
use App\Exceptions\ApiException;
use App\Util\ArrayUtil;


/**
 * 商品租赁SKU模型
 * Class GoodsRentSku
 * @package app\model
 */
class GoodsRentSku extends BaseModel
{
    const KEY = 'id';
    const TABLE = 'sp_goods_rent_sku';

    protected $table = self::TABLE;
    protected $primaryKey = self::KEY;
    protected $connection = 'mysql';

    const CREATED_AT = 'create_time';
    const UPDATED_AT = 'update_time';

    protected $guarded = [];

    protected $casts = [
        'create_time' => 'datetime:Y-m-d H:i:s',
        'update_time' => 'datetime:Y-m-d H:i:s',
    ];



    // 显式设置 snakeAttributes 为 true
    /**
     * 关联：规格值
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function goodsRentSkuMealValue()
    {
        return $this->hasMany(GoodsRentSkuMeal::class, 'goods_sku_id', 'id')->with('GoodsRentMealValue')
            ->select('id','goods_sku_id','meal_value_id','price','line_price', 'day_price', 'line_day_price','month_price','line_month_price');
    }


//    public function goods_rent_sku_meal_value()
//    {
//        return $this->hasMany(GoodsRentSkuMeal::class, 'goods_sku_id', 'id');
//    }
//
    public function goods_rent_sku_meal()
    {
        return $this->hasMany(GoodsRentSkuMeal::class, 'goods_sku_id', 'id');
    }

    public function goods_rent_meal()
    {
        return $this->belongsTo(GoodsRentMeal::class, 'meal_id', 'meal_id');
    }

    public function goodsRentMeal()
    {
        return $this->belongsTo(GoodsRentMeal::class, 'meal_id', 'meal_id')->select('meal_name','meal_id');
    }
    /**
     * 获取器：规格值ID集
     * @param $value
     * @return array|mixed
     */
    public function getSpecValueIdsAttribute($value)
    {
        return ArrayUtil::jsonDecode($value);
    }

    /**
     * 获取器：规格属性
     * @param $value
     */
    public function getGoodsPropsAttribute($value)
    {
        return ArrayUtil::jsonDecode($value);
    }



    /**
     * 获取器：规格值ID集
     * @param $value
     * @return array|mixed
     */
    public function getMealValueIdsAttribute($value)
    {
        return ArrayUtil::jsonDecode($value);
    }



    /**
     * 获取sku信息详情
     * @param int $goodsId
     * @param string $goodsSkuId
     * @return static|array|null
     */
    public static function detail(int $goodsId, string $goodsSkuId)
    {
        return static::get(['goods_id' => $goodsId, 'goods_sku_id' => $goodsSkuId], ['image']);
    }

    /**
     * 获取商品SKU列表
     * @param int $goodsId 商品ID
     * @param bool $withImage 是否携带sku封面图
     */
    public static function getSkuList(int $goodsId, bool $withImage = false)
    {
        return (new static)->with($withImage ? ['image'] : [])
            ->where('goods_id', '=', $goodsId)
            ->select();
    }

    /**
     * 生成skuList数据(写入goods_sku_id)
     * @param array $newSpecList
     * @param array $skuList
     * @return array
     */
    public static function getNewSkuList(array $newSpecList, array $newMealList,array $skuList): array
    {
        foreach ($skuList as &$skuItem) {
            if(!isset($newMealList[$skuItem['groupMealKey']])||empty($newMealList[$skuItem['groupMealKey']])){
                throw new ApiException('请上传正确的套餐键值');
            }

            $skuItem['specValueIds'] = static::getSpecValueIds($newSpecList, $skuItem['skuKeys']);
            $skuItem['goodsProps'] = static::getGoodsProps($newSpecList, $skuItem['skuKeys']);
            $skuItem['goods_sku_id'] = $newMealList[$skuItem['groupMealKey']]['meal_id'].'_'.implode('_', $skuItem['specValueIds']);
            $skuItem['mealValueIds'] =$newMealList[$skuItem['groupMealKey']]['valueList'];
            $skuItem['meal_id'] =$newMealList[$skuItem['groupMealKey']]['meal_id'];

        }
        return $skuList;
    }

    public static function checkSkuData($skuList)
    {
        foreach ($skuList as &$skuItem) {
            foreach ($skuItem['rentPrices'] as $key=>$rentPrice){
                if(empty($rentPrice)){
                    throw new ApiErrorException('请填写租赁价格');
                }
//                if($rentPrice-$skuItem['buyout_price']<0){
//                    throw new ApiErrorException('租赁价格不能小于买断价');
//                }
//
//                if(isset($skuItem['rentLinePrices'])&&$skuItem['rentLinePrices']&&$skuItem['rentLinePrices'][$key]&&$skuItem['rentLinePrices'][$key]>0&&$skuItem['rentLinePrices'][$key]-$skuItem['buyout_price']<0){
//                    throw new ApiErrorException('租赁原价价格不能小于买断价');
//                }

            }
        }
    }

    /**
     * 根据$skuKeys生成规格值id集
     * @param array $newSpecList
     * @param array $skuKeys
     * @return array
     */
    private static function getSpecValueIds(array $newSpecList, array $skuKeys): array
    {
        $goodsSkuIdArr = [];

        foreach ($skuKeys as $skuKey) {
            $groupItem = ArrayUtil::arraySearch($newSpecList, 'key', $skuKey['groupKey']);
            $specValueItem = ArrayUtil::arraySearch($groupItem['valueList'], 'key', $skuKey['valueKey']);
            $goodsSkuIdArr[] = $specValueItem['spec_value_id'];
        }
        return $goodsSkuIdArr;
    }

    /**
     * 根据$skuKeys生成规格属性记录
     * @param array $newSpecList
     * @param array $skuKeys
     * @return array
     */
    private static function getGoodsProps(array $newSpecList, array $skuKeys): array
    {
        $goodsPropsArr = [];
        foreach ($skuKeys as $skuKey) {
            $groupItem = ArrayUtil::arraySearch($newSpecList, 'key', $skuKey['groupKey']);
            $specValueItem = ArrayUtil::arraySearch($groupItem['valueList'], 'key', $skuKey['valueKey']);

            $goodsPropsArr[] = [
                'group' => ['name' => $groupItem['spec_name'], 'id' => $groupItem['spec_id'], 'groupKey' => $skuKey['groupKey']],
                'value' => ['name' => $specValueItem['spec_value'], 'id' => $specValueItem['spec_value_id'],'key' =>$skuKey['valueKey']],
            ];
        }
        return $goodsPropsArr;
    }

    /**
     * 更新商品sku记录
     * @param int $goodsId
     * @param int $specType
     * @param array $skuList
     * @return array|bool|false
     */
    public static function edit(int $goodsId, array $skuList = [])
    {
        // 删除所有的sku记录
        static::query()->where('goods_id',$goodsId)->delete();
        // 新增商品sku记录
        return static::add($goodsId,  $skuList);
    }
    /**
     * 新增商品sku记录
     * @param int $goodsId
     * @param array $newSkuList
     * @param int $specType
     * @return array|bool|false
     */
    public static function add(int $goodsId,  array $newSkuList = [])
    {
        $business_type=Goods::where('id',$goodsId)->value('business_type');


        foreach ($newSkuList as $skuItem) {
                $dataset =  [
                    'goods_sku_id' => $skuItem['goods_sku_id'],
                    'goods_sku_no' => $skuItem['goods_sku_no'] ?: '',
                    'stock_num' => $skuItem['stock_num'] ?: 0,
                    'goods_props' => json_encode($skuItem['goodsProps']),
                    'spec_value_ids' => json_encode($skuItem['specValueIds']),
                    'meal_value_ids' =>  json_encode($skuItem['mealValueIds']),
                    'buyout_price' => $skuItem['buyout_price'] ?: '',
                    'buyout_type' => $skuItem['buyout_type'] ?: 0,
                    'goods_id' => $goodsId,
                    'off_sale' => $skuItem['off_sale'],
                    'meal_id' => $skuItem['meal_id'],
                ];
              $sku= (new static)->create($dataset);

            if(count($skuItem['rentPrices'])!=count($skuItem['mealValueIds'])){
                throw  new ApiException('请输入正确的租赁价格');
            }
                if ($skuItem['rentPrices']) {
                    $goodsSkuMeal=[];
                    foreach ($skuItem['rentPrices'] as $key=>$rentPrice){

                        $day_price=0;
                        $month_price=0;
                        $line_day_price=0;
                        $line_month_price=0;
                        if($business_type==GoodsBusinessEnum::RENT()->getKey()){
                            $day_price=bcdiv($rentPrice, $skuItem['mealValueIds'][$key]['meal_value'],2);
                            $line_day_price=$skuItem['rentLinePrices'][$key]>0?bcdiv($skuItem['rentLinePrices'][$key], $skuItem['mealValueIds'][$key]['meal_value'],2):0;
                        }else if($business_type==GoodsBusinessEnum::LEASE()->getKey()&&$skuItem['mealValueIds'][$key]['meal_value']<=12){
                            $month_price=bcdiv($rentPrice, $skuItem['mealValueIds'][$key]['meal_value'],2);
                            $line_month_price=$skuItem['rentLinePrices'][$key]>0?bcdiv($skuItem['rentLinePrices'][$key], $skuItem['mealValueIds'][$key]['meal_value'],2):'';
                        }

                        $goodsSkuMeal[]= [
                            'goods_sku_id' => $sku->id,
                            'meal_value_id' => $skuItem['mealValueIds'][$key]['meal_value_id'],
                            'price' => $rentPrice,
                            'month_price' => $month_price,
                            'day_price' => $day_price,
                            'line_month_price' => $line_month_price,
                            'line_day_price' => $line_day_price,
                            'line_price' => !empty($skuItem['rentLinePrices'][$key])?$skuItem['rentLinePrices'][$key]:'0',
                            'create_time' => date('Y-m-d H:i:s'),
                            'update_time' => date('Y-m-d H:i:s'),
                        ];
                    }
                   GoodsRentSkuMeal::insert($goodsSkuMeal);
                }
            }
    }


    /**
     * 获取库存总数量 (根据sku列表数据)
     * @param array $skuList
     * @return float|int
     */
    public static function getStockTotal(array $skuList)
    {
        return (int)ArrayUtil::getArrayColumnSum($skuList, 'stock_num');
    }

    /**
     * 获取商品价格高低区间 (根据sku列表数据)
     * @param array $skuList
     * @return array
     */
    public static function getMinPrice($goods_id)
    {
        $business_type=Goods::query()->where('id',$goods_id)->value('business_type');
        $goodsSkuIds = static::query()->where('goods_id',$goods_id)->select('id');

        if($business_type==GoodsBusinessEnum::RENT()->getKey()){
            $res= GoodsRentSkuMeal::query()->whereIn('goods_sku_id',$goodsSkuIds)->selectRaw('MIN(day_price) as min_price, MIN(line_day_price) as min_line_price,meal_value_id')->first()->toArray();

        }else if($business_type==GoodsBusinessEnum::LEASE()->getKey()){
            $res= GoodsRentSkuMeal::query()->whereIn('goods_sku_id',$goodsSkuIds)->selectRaw('MIN(month_price) as min_price, MIN(line_month_price) as min_line_price,meal_value_id')->first()->toArray();

        }
        return $res;
    }

    /**
     * 获取划线价格高低区间 (根据sku列表数据)
     * @param array $skuList
     * @return array
     */
    public static function getGoodsMinLeaseTerm($meal_value_id)
    {
        return GoodsRentMealValue::query()->where('meal_value_id',$meal_value_id)->value('meal_value');
    }
}
